<template>
    <el-card 
        v-loading="isLoading"
        element-loading-text="加载中..."
        element-loading-background="rgba(122, 122, 122, 0.2)"
        class="box-card"
    >
        <template 
           #header
        >
            <div class="card-header">
                <el-button 
                    v-if="showButton"
                    link
                    type="danger"
                    :disabled="imageList2.length == 0"
                    @click="delImg(currentIndex)"
                >
                    删除
                </el-button>
                <div style="flex: 1;text-align: center;">{{ title }}（{{ imageList2.length }}）</div>
                <el-upload
                    v-if="showButton"
                    v-model:file-list="fileList"
                    action="/child/childImage/upload"
                    :headers="{
                        token: store.openid,
                    }"
                    :data="{}"
                    name="file"
                    :show-file-list="false"
                    ref="uploadRef"
                    :auto-upload="true"
                    accept="image/*"
                    multiple
                    :limit="limit"
                    list-type="picture"

                    :on-preview="handlePreview"
                    :on-remove="handleRemove"
                    :on-exceed="handleExceed"
                    :on-change="handleChange"
                    :on-success="handleSuccess"
                    :on-error="handleError"

                    :before-remove="beforeRemove"
                    :before-upload="beforeUpload"
                >
                    <el-button 
                        link
                        type="primary"
                        :disabled="imageList2.length > limit"
                    >
                        上传
                    </el-button>
                </el-upload>
            </div>
        </template>
        <div class="block">
            <el-carousel 
                :autoplay="false"
                trigger="click"
                indicator-position="none"
                @change="carouselChange"
            >
                <el-carousel-item 
                    v-for="(item,index) in imageList2"
                    :key="index"
                >
                    <el-image 
                        style="width: 100%; height: 100%;"
                        :src="item"
                        :preview-src-list="imageList2"
                        :initial-index="index"
                        fit="cover"
                        loading="lazy"
                        preview-teleported                        
                    >
                    </el-image>
                </el-carousel-item>
            </el-carousel>
        </div>
    </el-card>
</template>
  
<script lang="ts" setup>
    // ！！！注意本组件只允许放在需要监听滚动页面的最底部，因为我们是通过父元素的节点获得内部所有子元素的高度所以必须要放在父元素中的最底部
    import { ref, reactive, markRaw, onBeforeMount, onMounted, onBeforeUnmount, nextTick, computed, watch } from 'vue'
    import type { Ref, Raw } from 'vue'
    import { useRoute, useRouter } from 'vue-router'
    import { storeToRefs } from 'pinia'
    import { useStore } from '@/store'
    import { ElMessage, ElMessageBox } from 'element-plus'
    import { getUploadImageApi } from '@/apis'

    import Compressor from "compressorjs";
    // const props = withDefaults(defineProps<{
    //     list?: any[], 
    // }>(), {
    //     list: () => [],
    // })
    // 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'
    const store = useStore()

    const prefix = '/child/childImage/show?fileName='
    const isLoading: Ref<boolean> = ref(false)
    const loadingNum: Ref<number> = ref(0)
    const currentIndex: Ref<number> = ref(0)
    const imageList2: Ref<string[]> = ref([]) //根据生成的图片

    const fileList: Ref<any[]> = ref([])
    const uploadRef: Ref<any> = ref(null)
    const { title = '', limit = 100, showButton = true } = defineProps<{
        title?: string, 
        limit?: number, 
        showButton?: boolean, 
    }>()

    const imageStr = defineModel<string>('imageStr', {
        required: false,
        default: ''
    })

    watch(imageStr, (nval, oval) => {
        // console.log(nval)
        // console.log(fileList.value)
        if (nval && nval.split(',').length > fileList.value.length) {
            isLoading.value = true
            imageList2.value = []
            fileList.value = []
            let fun = async () => {
                for (let i in nval.split(',')) {
                    try {
                        let res: any = await getUploadImageApi(nval.split(',')[i])
                        imageList2.value.push(res.data) 
                        fileList.value.push({
                            status: 'success',
                            url: res,
                            response: {
                                data: {
                                    fileName: nval.split(',')[i].split(prefix)[1],
                                    status: 'OK'
                                }
                            }
                        })
                    } catch(err) {
                        // 就算图片出现问题，这里也可以让数量对上
                        imageList2.value.push('') 
                        fileList.value.push({
                            status: 'success',
                            url: '',
                            response: {
                                data: {
                                    fileName: nval.split(',')[i].split(prefix)[1],
                                    status: 'OK'
                                }
                            }
                        })
                    } finally {
                        // console.log(Number(i)+1)
                        // console.log(nval.split(',').length)
                        if (Number(i)+1 == nval.split(',').length) {
                            isLoading.value = false
                        }
                    }
                }
            }
            fun()
            loadingNum.value = nval.split(',').length

        }
    }, {
        immediate: true,
    })

    const carouselChange = (nVal, oVal) => {
        currentIndex.value = nVal
    }

    const delImg = (index) => {
        if (fileList.value.length > 0) {
            let arr = imageStr.value.split(',')
            arr.splice(index, 1)
            imageStr.value = arr.join(',')

            fileList.value.splice(index, 1)
            imageList2.value.splice(index, 1)
        }
    }

    // 文件列表移除文件时的钩子
    const handleRemove = (file, uploadFiles) => {
        // console.log(file, uploadFiles)
    }

    // 点击文件列表中已上传的文件时的钩子
    const handlePreview = (uploadFile) => {
        // console.log(uploadFile)
    }
    // 上传文件之前的钩子，参数为上传的文件， 若返回false或者返回 Promise 且被 reject，则停止上传。
    const beforeUpload = (rawFile) => {
        // console.log(rawFile)
        isLoading.value = true
        if (!rawFile.type.includes('image/jpeg') &&  !rawFile.type.includes('image/png')) {
            isLoading.value = false
            ElMessage.closeAll()
            ElMessage.error('请上传jpg或者png格式图片!')
            return false
        } else if (rawFile.size / 1024 / 1024 > 2) {
            // ElMessage.error('图片大小不能大于 2MB!')
            // return false
            return new Promise((resolve, reject) => {
                new Compressor(rawFile, {
                    quality: 0.6,
                    success(result) {
                        // 压缩成功后的处理
                        const compressedFile = new File([result], rawFile.name, { type: result.type });
                        // 可以在这里预览、上传或者做其他处理
                        // console.log("Compressed file:", compressedFile);
                        // 如果需要上传，可以在这里执行上传操作
                        resolve(compressedFile);
                    },
                    error(err) {
                        reject("压缩失败");
                        // console.log("Compressor error:", err.message);
                    }
                })
            })
            // new Compressor(file, options, callback);
            // file: 要压缩的文件对象。
            // options:
            // quality: 压缩质量，默认值为 0.6。对于 JPEG 图像，较低的值会导致更小的文件大小但画质较差；对于 PNG 图像，建议使用 1 来保持透明度。
            // maxWidth: 最大宽度，默认为 1600。
            // maxHeight: 最大高度，默认为 1600。
            // resize: 是否自动调整尺寸，默认为 true。
            // mimeType: 输出文件的 MIME 类型，默认为原文件类型。
            // convertSize: 将文件转换为小于指定大小的字节数，默认为 Infinity。
            // rotate: 自动旋转图片，根据 EXIF 数据，默认为 false。
            // callback: 一个可选的回调函数，当压缩完成时会被调用。
                        
        }
        return true
    }
    // 删除文件之前的钩子，参数为上传的文件和文件列表， 若返回 false 或者返回 Promise 且被 reject，则停止删除。
    const beforeRemove = (uploadFile, uploadFiles) => {
        return true;
    }
    // 当超出限制时，执行的钩子函数
    const handleExceed = (files, uploadFiles) => {
        ElMessage.closeAll()
        ElMessage.warning(
            `上传数量超出限制`
        )
    }
    // 文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
    const handleChange = (files, uploadFiles) => {
        // console.log(files)
        // console.log(uploadFiles)
        // ElMessage.warning(
        //     `文件状态改变时的钩子`
        // )
    }

    // 文件上传成功时的钩子
    const handleSuccess = async (res, files, uploadFiles) => {
        // console.log(res)
        // console.log(files)
        // console.log(uploadFiles)
        // console.log(fileList.value)


        // let arr = imageStr.value ? imageStr.value.split(',') : []
        // arr.push(prefix + res[0].fileName)
        // imageStr.value = arr.join(',')
        // imageList2.value.push(files.url) 
        let arr = []
        imageList2.value = []
        fileList.value.forEach((item, index) => {
            if (item.status == 'success' && item.response.code == 200) {
                // console.log(item)
                arr.push(prefix + item.response.data.fileName)
                imageList2.value.push(item.url) 
            }
        })
        imageStr.value = arr.join(',')

        loadingNum.value++
        console.log(loadingNum.value)
        console.log(fileList.value)
        if (loadingNum.value == fileList.value.length) {
            isLoading.value = false
        }
    }
    // 文件上传失败时的钩子
    const handleError = async (error, uploadFile, uploadFiles) => {
        // console.log(error)
        // console.log(uploadFile)
        // console.log(uploadFiles)
        // console.log(fileList.value)
        loadingNum.value++
        if (loadingNum.value == fileList.value.length) {
            isLoading.value = false
        }
    }
</script>

<style lang="scss" scoped>
    .box-card {
        width: 100%;
    }
    .card-header {
        display: flex;
        justify-content: space-between;
    }
</style>